// zc_stack.c

#include <libzc.h>

//// zc_stack_t.
//struct zc_stack_t {
//    int size;
//    int length;
//    void **data;
//};

// create.
struct zc_stack_t *zc_stack_create(int size)
{
    struct zc_stack_t *s = malloc(sizeof(struct zc_stack_t));
    if(s == NULL)
    {
        return NULL;
    }

    void *p = malloc(sizeof(void *) * size);
    if(p != NULL)
    {
        s->length = 0;
        s->size = size;
        s->data = p;
    }
    else
    {
        free(s);
        s = NULL;
    }

    return s;
}

// realloc
int zc_stack_realloc(struct zc_stack_t *s, int size)
{
    if(s->length > size)
    {
        return -1;
    }

    if(s != NULL)
    {
        void *p = malloc(sizeof(void *) * size);
        if(p != NULL)
        {
            memcpy(p, s->data, sizeof(void *)*s->length);
            free(s->data);
            s->size = size;
            s->data = p;
            return 0;
        }
    }

    return -1;
}

// push.
int zc_stack_push(struct zc_stack_t *s, void *d)
{
    if(s->length == s->size)
    {
        return -1;
    }

    s->data[s->length] = d;
    s->length++;

    return 0;
}

// pop.
void *zc_stack_pop(struct zc_stack_t *s)
{
    void *p = NULL;

    if(s->size > 0 && s->length > 0)
    {
        p = s->data[s->length-1];
        s->length--;
    }

    return p;
}

// length.
int zc_stack_length(struct zc_stack_t *s)
{
    return s->length;
}

// is full. return 0 is full.
int zc_stack_isfull(struct zc_stack_t *s)
{
    return (s->size - s->length);
}

// clear.
void zc_stack_clear(struct zc_stack_t *s)
{
    s->length = 0;

    return;
}

// destory.
void zc_stack_destory(struct zc_stack_t *s)
{
    if(s != NULL)
    {
        if(s->data != NULL)
        {
            free(s->data);
        }
        free(s);
    }

    return;
}

